<?php
namespace app\common\model;
use app\common\cache\CacheData;

class Bonus extends Base
{

	public function cacheData(){
		$data = $this->select();
		if($data){
			foreach($data as &$value):
				$value=$value->toArray();
			endforeach;
		}
		return $data;
	}
	
	/**
     * 奖金缓存
     * @param  [type] $bonus_name [description]
     * @return [type]             [description]
     */
    public static function bonusData($bonus_name=null){
        $CACHE = CacheData::getInstance('Bonus');
        $CACHE -> updateCache();
        $cacheData = $CACHE -> readCache();
        $data = [];
        foreach($cacheData as $cache):
            $data[$cache['bonus_name']] = $cache;
        endforeach;
        if(!is_null($bonus_name)){
            if(isset($data[$bonus_name])):
                return $data[$bonus_name];
            else:
                return false;
            endif;
        }else{
            return $data;
        }
    }

    /**
     * 计算昨日全体分红
     * @return [type] [description]
     */
    public function world(){
        $memberModel = new \app\common\model\Member;
        $memberScoreDailyModel = new \app\common\model\MemberScoreDaily;
        // 昨日新增业绩
        //$day = date("Ymd",strtotime("-1 day"));
        $day = date("Ymd");
        $init_uid = Option::getOne('init_uid');
        // 判断该天是否已经结算过全体分红
        if($memberScoreDailyModel->where(['uid'=>$init_uid,'day'=>$day])->value('is_world_mathed')){
            $this->error = '该日全体分红已经结算过';
            return false;
        }
        // 判断昨日业绩累计是否计算完成
        if(false==model('member_score')->isDayScoreDealed($day)){
            $this->error = '该日业绩累计尚未完成，无法结算全体分红';
            return false;
        }
        
        // 昨日新增业绩总量
        $all_score = $memberScoreDailyModel->where(['uid'=>$init_uid,'day'=>$day])->value('score');
        // 可以享受全体分红用户
        $members = $memberModel->where(['is_world'=>1])->field(['id','level_id'])->select();
        if(!$members)
            return true;
        foreach($members as &$member):
            $member = $member->toArray();
        endforeach;

        // 可以享受全体分红用户的自身业绩总和
        $member_score_total = $memberModel->where(['is_world'=>1])->value('SUM(score_own) AS total');

        // 获取本插件配置数据
        // 货币配置
        $coinConfig = BonusConfig::bonusConfig(__FUNCTION__,'coin');
        $coinConfig = unserialize($coinConfig['config_value']);
        // 全局比例
        $rateConfig = BonusConfig::bonusConfig(__FUNCTION__,'rate');
        $rateConfig = unserialize($rateConfig['config_value']);
        $rate = $rateConfig['rate'];
        // 等级倍数配置
        $levelConfig = BonusConfig::bonusConfig(__FUNCTION__,'level');
        $levelConfig = unserialize($levelConfig['config_value']);
        unset($levelConfig[0]);

        $bonusMemberTotalModel = model('bonus_member_total');
        $bonusRecordModel = model('bonus_record');

        $bonusRecordModel->startTrans();
        try{
            foreach($members as $m):
                $member_score = Level::levelData($m['level_id'])['score'];
                $bonus = $member_score*($all_score*$rate/100/$member_score_total);
                // 判断是否达到封顶值
                // 该会员等级配置倍数
                $multiple = $levelConfig[$m['level_id']]['multiple'];
                // 该用户已经分红总额
                $total = $bonusMemberTotalModel->where(['bonus_name'=>__FUNCTION__,'uid'=>$m['id']])->value('total');
                if(!$total){
                    $total = 0;
                }
                if(($total+$bonus)/$member_score>$multiple){
                    $final_bonus = abs($member_score*$multiple-$total);
                    $remark = '['.$day.']全体分红'.$bonus.'；因总分红超过等级倍数限制，实际分红'.$final_bonus;
                    $new_total = $member_score*$multiple;
                    //关闭用户is_world
                    $memberModel->where(['id'=>$m['id']])->update(['is_world'=>0]);
                }else{
                    $final_bonus = $bonus;
                    $remark = '['.$day.']全体分红'.$final_bonus;
                    $new_total = $total+$final_bonus;
                }
                // 更新该类奖金总数
                $bonusMemberTotalModel->where(['bonus_name'=>__FUNCTION__,'uid'=>$m['id']])->update(['total'=>$new_total]);
                // 奖金记录
                $record = [];
                foreach($coinConfig as $conf):
                    $record[] = [
                        'bonus_name' => __FUNCTION__,
                        'reason_uid' => 0,
                        'effect_uid' => $m['id'],
                        'coin_id' => $conf['coin_id'],
                        'amount' => $final_bonus*$conf['config']/100,
                        'remark' => $remark,
                        'reason_time' => strtotime($day),
                    ];
                endforeach;
                $bonusRecordModel -> saveAll($record);

            endforeach;
            // 标记该日已经结算
            $memberScoreDailyModel->where(['uid'=>$init_uid,'day'=>$day])->update(['is_world_mathed'=>1]);

            $bonusRecordModel->commit();
        }catch(\Exception $e){
            $bonusRecordModel->rollback();
            $this->error=$e->getMessage();
            return false;
        }
        return true;
    }

    public function jiaquan(){
        $memberModel = model('member');
        $memberScoreDailyModel = model('member_score_daily');
        // 昨日新增业绩
        //$day = date("Ymd",strtotime("-1 day"));
        $day = date("Ymd");
        $init_uid = Option::getOne('init_uid');
        // 判断该天是否已经结算过加权分红
        if($memberScoreDailyModel->where(['uid'=>$init_uid,'day'=>$day])->value('is_jiaquan_mathed')){
            $this->error = '该日加权分红已经结算过';
            return false;
        }
         // 判断昨日业绩累计是否计算完成
        if(false==model('member_score')->isDayScoreDealed($day)){
            $this->error = '该日业绩累计尚未完成，无法结算加权分红';
            return false;
        }
        
        // 昨日新增业绩总量
        $all_score = $memberScoreDailyModel->where(['uid'=>$init_uid,'day'=>$day])->value('score');
        
        // 可享受加权分红的每个等级的人数
        $level_member_num = $memberModel->
            where(['is_share'=>1])->
            field(['level_id','count(level_id) as num'])->
            group('level_id')->
            select();
        foreach($level_member_num as &$value):
            $value = $value->toArray();
        endforeach;
        $level_member_num = array_combine(array_column($level_member_num,'level_id'),$level_member_num);
        //dump($level_member_num);die;

        // 可以享受全体分红用户的自身业绩总和
        $member_score_total = $memberModel->where(['is_share'=>1])->value('SUM(score_own) AS total');

        // 获取本插件配置数据
        // 货币配置
        $coinConfig = BonusConfig::bonusConfig(__FUNCTION__,'coin');
        $coinConfig = unserialize($coinConfig['config_value']);
        // 等级比例、倍数配置
        $rateConfig = BonusConfig::bonusConfig(__FUNCTION__,'levels');
        $rateConfig = unserialize($rateConfig['config_value']);
        $rateConfig = array_combine(array_column($rateConfig, 'level_id'), $rateConfig);

        // 每个等级的分红计算
        $level_bonus = [];
        foreach($level_member_num as $key => $value):
            $rate = $rateConfig[$key]['rate'];
            $level_bonus_total = $all_score*$rate/100;
            $level_bonus[$key] = $level_bonus_total/$value['num'];
        endforeach;

        // 可以享受加权分红用户
        $members = $memberModel->where(['is_share'=>1])->field(['id','level_id'])->select();
        if(!$members)
            return true;
        foreach($members as &$member):
            $member = $member->toArray();
        endforeach;

        $bonusMemberTotalModel = model('bonus_member_total');
        $bonusRecordModel = model('bonus_record');

        $bonusRecordModel->startTrans();
        try{
            foreach($members as $m):
                $member_score = Level::levelData($m['level_id'])['score'];
                // 该用户等级的分红数额
                $bonus = $level_bonus[$m['level_id']];
                // 判断是否达到倍数限制
                $multiple = $rateConfig[$m['level_id']]['multiple'];
                // 已经分红总额
                $total = $bonusMemberTotalModel->where(['bonus_name'=>__FUNCTION__,'uid'=>$m['id']])->value('total');
                if(!$total){
                    $total = 0;
                }
                if(($total+$bonus)/$member_score>$multiple){
                    $final_bonus = abs($member_score*$multiple-$total);
                    $remark = '['.$day.']加权分红'.$bonus.'；因总分红超过等级倍数限制，实际分红'.$final_bonus;
                    $new_total = $member_score*$multiple;
                    //关闭用户is_share
                    $memberModel->where(['id'=>$m['id']])->update(['is_share'=>0]);
                }else{
                    $final_bonus = $bonus;
                    $remark = '['.$day.']加权分红'.$final_bonus;
                    $new_total = $total+$final_bonus;
                }
                // 更新该类奖金总数
                $bonusMemberTotalModel->where(['bonus_name'=>__FUNCTION__,'uid'=>$m['id']])->update(['total'=>$new_total]);
                // 奖金记录
                $record = [];
                foreach($coinConfig as $conf):
                    $record[] = [
                        'bonus_name' => __FUNCTION__,
                        'reason_uid' => 0,
                        'effect_uid' => $m['id'],
                        'coin_id' => $conf['coin_id'],
                        'amount' => $final_bonus*$conf['config']/100,
                        'remark' => $remark,
                        'reason_time' => strtotime($day),
                    ];
                endforeach;
                $bonusRecordModel -> saveAll($record);
            endforeach;

            // 标记该日已经结算
            $memberScoreDailyModel->where(['uid'=>$init_uid,'day'=>$day])->update(['is_jiaquan_mathed'=>1]);

            $bonusRecordModel->commit();
        }catch(\Exception $e){
            $bonusRecordModel->rollback();
            $this->error=$e->getMessage();
            return false;
        }
        return true;

    }
}
